package intermouse;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Hangya osztály
 * 
 * @author Sőre András, Demény Fruzsina Gyöngyi
 * @version 1.0
 * @since 2013-03-24
 */
public class Ant extends FieldObject {

	/**
	 * A hátralevő bolyongással töltött körök száma.
	 */
	private int wanderMoves = 0;
	
	private Field prev = null;

	private int direction;
	/**
	 * Konstruktor
	 * 
	 * Az Ant osztály konstruktora
	 */
	public Ant() {
		super();
		fieldType = FieldTypes.Ant;
		direction = new Random().nextInt(6);
	}

	/**
	 * @param stone
	 *            : a kő, mely rálépne a hangyára
	 * @param isFirst
	 *            : az első meghívása-e a függvénynek
	 * @param direction
	 *            : megadja az irányt
	 * @return megadja a paraméterként kapott kőnek hogy a field mezőre
	 *         léphet-e.
	 */
	boolean canStep(Stone stone, boolean isFirst, int direction) {
		Logger.printToConsole(">> FieldObject.canStep(Stone, boolean, int) : bool");
		this.setDead(true);
		Logger.printToConsole("<< return");
		return true;
	}
	
	/**
	 * Beállítja a dead kapcsolót.
	 */
	void setDead(boolean dead) {
		Logger.printToConsole(">> FieldObject.setDead(boolean) : void");
		super.setDead(dead);
		//Kiegészítjük az ősosztályt azzal, hogy a pontokat is módosítjuk
		GameState.getInstance().addToPlayerScore(25);
		Logger.printToConsole("<< return");
	}

	/**
	 * Meghívódik ha a hangyának sikerült ennie, a wanderMoveshez ad hozzá, és
	 * bolyongani kezd a hangya.
	 */
	public void eats() {
		Logger.printToConsole(">> Ant.eats() : void");
		setWanderMoves(16);
		Logger.printToConsole("<< return");
	}

	/**
	 * 
	 * A hangyát megtámadta az egyik Malicious objektum, ezért a hangya
	 * FieldObject osztálytól örökölt dead attribútumát beállítjuk, továbbá true
	 * értéket adunk vissza.
	 * 
	 * @return visszaadja, hogy az attack sikeres volt.
	 */
	public boolean attack() {
		Logger.printToConsole(">> Ant.attack() : boolean");
		this.setDead(true);
		TestCommandParser.log("Ant dies at " + this.field.toString() +".");
		Logger.printToConsole("<< return");
		return true;
	}

	/**
	 * A hangya mozgásáért felelős függvény. Lekérdezi a szomszédos mezőkön
	 * található szagokat, és azok alapján rangsorolja őket, amíg talál egy
	 * olyat amire rá tud lépni a szomszéd mezők közül
	 */
	public void beginRound() {
		try {
			Logger.printToConsole(">> Ant.beginRound() : void");
			field.addSmell(new AntSmell());
			TestCommandParser.log("Ant leaves AntSmell at " + this.field.toString() +".");
			List<Field> temp = field.getAdjacentFields();
			List<Field> aFields = new ArrayList<Field>();
			
			Random r=new Random();
			
			for (Field t : temp) {
				aFields.add(t);
			}
//			if(GameState.getInstance().getUseRandomSteps()){
//					java.util.Collections.shuffle(aFields,new Random());
//			}
			boolean flag = true;
			if (getWanderMoves() == 0 && GameState.getInstance().getUseRandomSteps() && r.nextFloat() < 0.3) {
				while (flag) {
					Field chosenAntField = null;
					int strongestAntSmell = -1;
					Field chosenFoodField = null;
					
					if (aFields.size() >= 1)
					{
						if(r.nextFloat()<0.2 || direction>=aFields.size())
						direction = r.nextInt(aFields.size());
						chosenFoodField = aFields.get(direction);
					}
					int strongestFoodSmell = -1;
					for (Field f : aFields) {
						List<Smell> aSmells = f.getSmells();
						if (aSmells.size()>0) {
							for (Smell s : aSmells) {
								if (!s.deodorantReaction())
									if (strongestFoodSmell < s.getStrength()) {
										strongestFoodSmell = s.getStrength();
										chosenFoodField = f;
										direction = aFields.indexOf(f);
								} else {
									if (strongestAntSmell < s.getStrength()) {
										strongestAntSmell = s.getStrength();
										chosenAntField = f;
										direction = aFields.indexOf(f);
									}
								}
							}
						}
					}
					if (chosenFoodField != null) {
						if (chosenFoodField.canStep(this)) {
							flag = false;
							TestCommandParser.log("Ant moves from "+ this.field.toString() +" to "+chosenFoodField.toString()+".");
							setField(chosenFoodField);
						} else {
							aFields.remove(direction);
						}
					} else if (chosenAntField != null  && prev!=chosenFoodField) {
						if (chosenAntField.canStep(this)) {
							flag = false;
							TestCommandParser.log("Ant moves from "+ this.field.toString() +" to "+chosenAntField.toString()+".");
							setField(chosenAntField);
							prev = chosenAntField;
						} else {
							aFields.remove(direction);
						}
					} else {
						Logger.printToConsole("Warning! Ant is stuck and can not move to another field");
						flag = false;
					}
				}
			} else {
//				if(GameState.getInstance().getUseRandomSteps()){		
//						java.util.Collections.shuffle(aFields,new Random());
//				}
				Field nextField = null;
				while (flag) {
					if(aFields.size()>0)
					nextField = aFields.get(r.nextInt(aFields.size()));
					if (nextField == null) {
						flag = false;
						Logger.printToConsole("Warning! Ant is stuck and can not move to another field");
					} else if (nextField.canStep(this)) {
						TestCommandParser.log("Ant moves from "+ this.field.toString() +" to "+nextField.toString()+".");
						setField(nextField);
						flag = false;
					} else {
						aFields.remove(nextField);
					}
				}
				setWanderMoves(wanderMoves--);
			}
			
			Logger.printToConsole("<< return");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Meghívódik, ha a hangya egy adott mezőre szeretne lépni, meghívja a
	 * megfelelő mező canStep(Ant ant) függvényét.
	 * 
	 * @param ant a hangya referenciája mely rá akar lépni
	 * @return a hangya nem léphet rá másik hangyára
	 */
	public boolean canStep(Ant ant) {
		Logger.printToConsole(">> Ant.canStep() : void");
		Logger.printToConsole("<< return");
		return true;
	}

	/**
	 * @return Visszaadja a hátralevő bolyongással töltött körök számát.
	 */
	public int getWanderMoves() {
		Logger.printToConsole(">> Ant.getWanderMoves() : int");
		Logger.printToConsole("<< return");
		return wanderMoves;
	}

	/**
	 * @param mennyi
	 *            legyen a hangya bonyolgással töltött körök száma. Beállítja a
	 *            bolyongással töltött körök számát.
	 */
	public void setWanderMoves(int value) {
		Logger.printToConsole(">> Ant.setWanderMoves(int) : void");
		this.wanderMoves = value;
		Logger.printToConsole("<< return");
		
	}
}
